package com.example.xucheng_security.auth.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.example.xucheng_security.auth.service.AuthService;
import com.example.xucheng_security.ucenter.mapper.XcMenuMapper;
import com.example.xucheng_security.ucenter.mapper.XcUserMapper;
import com.example.xucheng_security.ucenter.model.dto.AuthParamsDto;
import com.example.xucheng_security.ucenter.model.dto.XcUserExt;
import com.example.xucheng_security.ucenter.model.po.XcMenu;
import com.example.xucheng_security.ucenter.model.po.XcUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 通过user连接数据库 （进行springsecurity的用户登录管理）
 * @Author: Mr.Liu
 * @Date: created in 14:15 2023/3/6
 * @Modified By:
 */
@Slf4j
@Service
public class UserServiceImpl implements UserDetailsService {
    @Autowired
    XcMenuMapper menuMapper;
   @Autowired
    XcUserMapper xcUserMapper;
   @Autowired
   ApplicationContext applicationContext;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException{
        log.info("进入自定义用户的查询");
        //方式1：将传输的账号变成 json格式
        AuthParamsDto authParamsDto=null;
        try {
            authParamsDto = JSON.parseObject(s, AuthParamsDto.class);
        } catch (Exception e) {
            log.info("传输的认证信息不符合要求{}",s);
            throw new  RuntimeException("认证错误，格式不正确");
        }
        //获取账号
        String username = authParamsDto.getUsername();
        //登录类型
        String authType = authParamsDto.getAuthType();
        AuthService authService=applicationContext.getBean(authType+"_authservice",AuthService.class);
        XcUserExt xcUserExt = authService.execute(authParamsDto);
        return this.getUserPrincipal(xcUserExt);

        //通过用户名查询用户 方拾二：传输的是账号
//        XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, s));
//        //查询用户为空  则 返回空
//        Optional<XcUser> optionalXcUser=Optional.ofNullable(xcUser);
//        if (!optionalXcUser.isPresent()) {
//            return null;
//        }
//        //权限必须要存在   没有会报错
//        String[] authorities={"test"};
//        //方式一：
////        return User.withUsername(xcUser.getUsername()).password(xcUser.getPassword()).authorities(authorities).build();
////        方式二：
//        //思考：User.withUsername(xcUser.getUsername()) 可以扩种json串
//        // 将用户的所有信息都放在 这个串中 形式  如同 User.withUsername(“{“”：“”}”))
//        //密码设置为空
//        String  password=xcUser.getPassword();
//        xcUser.setPassword("");
//        String xcUserJson = JSON.toJSONString(xcUser);
//        return User.withUsername(xcUserJson).password(password).authorities(authorities).build();



    }

    /**
     * 将userExt封装成UserDetails对象
     * @param userExt
     * @return
     */
    public  UserDetails getUserPrincipal(XcUserExt userExt){
        String password=userExt.getPassword();
        //权限列表，存放的用户权限
        List<String> permissionList = new ArrayList<>();

        //根据用户id查询数据库中他的权限   将权限添加到springsecurity的jwt的字段串中
//       通过在controller中添加注解    @PreAuthorize("hasAuthority('p1')") 判断用户是否 有该权限
        // 更加细粒度的判断当前用户的权限  需要通过 当前用户的身份来进行划分
        List<XcMenu> xcMenus = menuMapper.selectPermissionByUserId(userExt.getId());
        xcMenus.forEach(menu->{
            permissionList.add(menu.getCode());
        });
        if(permissionList.size()==0){
            //用户权限,如果不加报Cannot pass a null GrantedAuthority collection
            permissionList.add("test");
        }

        String[] authorities= permissionList.toArray(new String[0]);
        //原来存的是账号，现在扩展为用户的全部信息(密码不要放)
        userExt.setPassword(null);
        String jsonString= JSON.toJSONString(userExt);
        UserDetails userDetails= User.withUsername(jsonString).password(password).authorities(authorities).build();
        return userDetails;
    }
}
